#include <iostream>
using namespace std;

#include <purewell/purewell.hpp>
#include <purewell/messagequeue.hpp>
using namespace purewell;

#include <sys/types.h>
#include <fcntl.h>
#include <errno.h>
#include <mqueue.h>
#include <sys/resource.h>

PWIOPoll* poll(PWIOPoll::create("select"));

class XMQ : public PWMessageQueue
{
public:
	void onEvent(PWIOPoll* io, int fd, int event)
	{
		cerr << "onEvent(" << io <<", " << fd << ", " << event << ")" << endl;
		if ( event & PWIO_R )
		{
			char buf[1024];
			ssize_t blen;
			size_t prio(0);
			blen = receive(buf, sizeof(buf), &prio);
			if ( blen > 0 )
			{
				cerr << "buffer: ";
				cerr.write(buf, blen) << endl;
				cerr << "prio: " << prio << endl;
			}
			else
			{
				cerr << strerror(errno) << endl;
			}
		}

		m_exit = true;
	}

	XMQ() : m_exit(false) {}

public:
	volatile bool m_exit;
};

XMQ mq;

void
sender(void)
{
	cerr << "sender!" << endl;
	const char buf[] = "Hello, world!";
	sleep(1);
	mq.send(buf, sizeof(buf), 0);
	mq.send(buf, sizeof(buf), 1);
	mq.send(buf, sizeof(buf), 2);
	mq.send(buf, sizeof(buf), 32000);
	mq.send(buf, sizeof(buf), 1);
	mq.send(buf, sizeof(buf), 0);
	cerr << "sender done" << endl;
}

void
recver(void)
{
	cerr << "receiver!" << endl;
	while ( poll->dispatch(1000) && !mq.m_exit ) {}
	cerr << "receiver done" << endl;
	mq.unlink();
}

int
main(int argc, char* argv[])
{
	if ( !mq.initialize("/mqtest.mq", O_CREAT|O_EXCL|O_RDWR, 0700,
		10, 1024) )
	{
		cerr << "failed to initialize message queue" << endl;
		cerr << strerror(errno) << endl;
		return -1;
	}
	else
	{
		cerr << "mq.handle == " << mq.getHandle() << endl;
		struct rlimit lim;
		getrlimit(RLIMIT_MSGQUEUE, &lim);
		cerr << "mq.cur: " << lim.rlim_cur << endl;
		cerr << "mq.max: " << lim.rlim_max << endl;
	}

	poll->add(&mq, PWIO_R);

	if ( fork() )
	{
		sender();
	}
	else
	{
		recver();
	}

}

